#-*-coding:utf-8-*-
# 第一次:
# 1 自我介绍
# 2 项目情况以及在项目中做的功能，印象特别深的bug怎么修复的
# 3 Tcp 三次握手，四次捂手都干了什么以及为什么断开时要四次握手
# Tcp是全双工协议
# 三次:第一次客户端发送一个数据包,其中syn位置1,表示请求建立客户端向服务端的通道
#      第二次服务端发送一个数据包,一个是ack位置1,表示已经确认了客户端向服务的的通道
#      其中还有一个syn位置1,表示请求建立服务端向客户端的通道
#      第三次客户端发送一个数据包,用来告诉服务端,服务端向客户端的通道已经建立
# 四次:第一次客户端发送一个数据包,其中fin位置1,客户端进入等待结束状态.
#      第二次服务端发送一个数据包,ACK位置1,此时客户端和服务端都处于等待关闭状态,
#      第三次服务端发送一个数据包,FIN位置1,服务器进入last-ack状态，等待客户端确认关闭通道
#      第四次客户端发送确认数据包,ACK位置1,客户端进入time-wait状态,此时服务端收到这个数据就关闭可服务端通向客户端的通道
#      而客户端通向服务端的通道,则需要等到2*MSL时间之后关闭.
#      由此可见双向通道都是在第四次握手之后关闭的,而且服务端关闭的要比客户端早
#为什么断开要四次:理论上建立和断开都是四次,只不过建立的时候把两次合并了,就成了三次.
# 建立时服务端收到syn包之后,可以直接发送syn+ack包给客户端;而断开时服务端并不会立即关闭通道,可能会有数据没有传完,
# 只能发送一个ack包,要等到所有数据都传完,才能发送Fin包
# 为什么不能两次握手:三次握手是为了保证双方都知道自己和对方的收发功能正常,如果只有两次则客户端知道自己收发正常,
# 知道服务端收发正常,服务端知道自己收发正常，知道客户端发正常，则不知道客户端收是否正常.
# udp 快没有tcp的握手,超时重传，拥塞控制等机制,所以不可靠
# 4 cocos2dx的垃圾回收机制，
# 引用计数 当一个Node调用autorelease是会把这个node放到autoreleasepool里面,如果这个node被addchild或者调用了retain()之后
# 其计数会+1,调用release之后引用计数减一,等到计数为0的时候就会被释放.
# 内存泄漏指程序对某段内存失去了控制权,从而造成内存上的浪费
# python垃圾回收
# 也是引用计数,原理基本上和cocos2dx的一样
# 手动删除对象
# del obj
# gc.collect()
# 5 循环引用
# 指两个模块相互引用
# 比如 a =[1,2,3,4,5,6] b = [1,5,8]
# a.append(b) b.append(a)
# 解决办法:1 显示调用gc.gollect() 2 标记清除，分代收集
# 哈希冲突，怎么解决的
# 由于hash算法不能保证key1 != key2 时hash(key1) != hash(key2)
# 所以会出现不同的key的hash值相同，这就是hash冲突
# 解决办法:开放地址法,链表法.
# 链接法:把hash值相同的key放到一个链表里面,在查找时如果对应多个元素,就遍历链表查找出来对应的对象
# 第二次
# 自我介绍+项目中做了哪些功能
# 中间问了js的东西,就不写了
# 1 快排
# 2 设计一个小游戏
# 3 优化内存,主要是指图片资源
# 当前项目中的优化
# 1 工程上:
# 删除冗余资源，即删除0引用的资源。
# 优化输出的资源,即对称的资源可以只出一半;
# 缩图,有些特殊的资源（比如纹理模糊/序列帧/停留时间短的图片）,可以只出1/3或者1/2
# 删减字库
# 2 程序上
# 减少dp（通常又称drawCall）
# 同屏ui尽量来自于一张大图
# 小的散图（头像，技能icon啊）合并成一张大图
# 新弹出来一个ui能让原来的隐藏就隐藏
#对于内存，我们常见的优化方式有：
#尽量做到按需加载，不加载未用到的UI资源，即不滥用缓存。
#对资源进行优化：优化UI资源尺寸，字体文件尺寸，提高合图使用率等等。
#优化制作：较费内存资源的动效（比如序列帧动画），尝试使用更省的制作方法。
#培养UI良好的拼接习惯，不滥用节点。
#贴图采用适当压缩策略
# 预缓存,异步加载，分帧加载
# 第三次 炎魂
# 1 自我介绍
# 2 问了公共的东西
# 闭包:内层函数可以访问外层函数的参数，变量.局部变量会常驻在内存中,但是会造成内存泄漏
#
# 闭包的作用：模拟私有方法
# 闭包的坑:引用的变量可能发生变化,在for循环内部var 声明的变量在循环结束之后局部变量已经达到最大值,
# 从而导致闭包方法里面用到的变量不正确.
# 内存泄漏,this指向问题.
# 值传递,引用传递,C# string ,类都是什么传递
# 值传递:调用时，将实参的值传递对应的形参，即为值传递。在函数中对任何形参值得修改都不会改变实参变量的值
# 引用传递:把实参的地址作为参数，形参所引用的该地址上的变量与传递的实参相同，方法体内相应形参值得任何改变都将影响到作为引用传递的实参
# 类和接口的区别:接口只有包含方法,而且不能有任何实现,而且接口可以多重继承.
# 3 算法。基本上都答出来了
# 常用排序:冒泡，选择，插入，堆排序，归并，快排。
# 快排实现思路
# 合并多个有序的链表
# 4 unity 和lua相关
# mono的生命周期:awake,onenbale,start,,fixedupdate,update,lateupdate,destroy.
# onEnable /on disbale:当object的active,enable改变时会触发onEnbale,onDisbale
# fixedupdate,update,lateupdate区别:
# update:每一帧li
# LateUpdate:是在所有 Update 方法调用之后被调用（语出圣典）
# FixedUpdate：固定更新。默认情况下，系统每0.02秒调用一次
# 总体来说，Update() 和 LateUpdate() 属于立即更新，更新之间的频率是不固定的，比如某一帧有一个耗时操作时，就会影响到下
# 一帧更新时间，所以对更新频率要求比较稳定的物理系统（如Rididbody）就不太适合在这里处理更新。
# FixedUpdate() 虽然是固定更新，但是其实也是相对固定的，比如某一帧耗了好几秒，它依然会卡住。
# 不过正常的程序会优化耗时操作，小范围的帧率波动是正常的，可以让它更新的时间间隔稍微长一点，这样它的更新是比较平滑的。
# 在实际的开发中，例如以秒为单位的倒计时，并不需要每一帧去判断时间，所以用 FixedUpdate 就再合适不过了。
# 在圣典里LateUpdate被解释成一句话：LateUpdate是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。
# 例如:当物体在Update里移动时，跟随物体的相机可以在LateUpdate里实现。这句我看了云里雾里的，后来看了别人的解释才明白过来。
#
# LateUpdate是晚于所有Update执行的。
# 例如：游戏中有2个脚步，脚步1含有Update和LateUpdate，脚步2含有Update，那么当游戏执行时，每一帧都是把2个脚步中的Update执行完后才执行LateUpdate 。
# 虽然是在同一帧中执行的，但是Update会先执行，LateUpdate会晚执行。
# 现在假设有2个不同的脚本同时在Update中控制一个物体，那么当其中一个脚本改变物体方位、旋转或者其他参数时，
# 另一个脚步也在改变这些东西，那么这个物体的方位、旋转就会出现一定的反复。
# 如果还有个物体在Update中跟随这个物体移动、旋转的话，那跟随的物体就会出现抖动。
# 如果是在LateUpdate中跟随的话就会只跟随所有Update执行完后的最后位置、旋转，这样就防止了抖动。
# lua 数据类型：number string nil boolean function table ,
# lua 没有int float 类型,都是number类型
# lua 实现类:基本原理用table实现类，和js类似。
# unity 协程:
# 　其实很简单，首先需要理解进程和线程是怎么一回事：
# 进程拥有自己独立的堆和栈，既不共享堆，亦不共享栈，进程由操作系统调度。
# 线程拥有自己独立的栈和共享的堆，共享堆，不共享栈，线程亦由操作系统调度(标准线程是的)。
# 协程和线程一样共享堆，不共享栈，协程由程序员在协程的代码里显示调度。
#  一个正在运行的应用程序在操作系统中被视为一个进程，进程可以包括一个或多个线程。
# 协程功能:1）延时（等待）一段时间执行代码；2）等某个操作完成之后再执行后面的代码。总结起来就是一句话：控制代码在特定的时机执行。
# IEnumerator func(){ return yeild xxx }
# xxx:null/waitForFixedUpdate/WaitForSeconds/www/
# unity 垃圾回收机制

# C#值类型,引用类型
# 值类型:值类型变量可以直接分配给一个值,继承制System.ValueType
# 引用类型:引用类型不包含存储在变量中的实际数据，但它们包含对变量的引用。继承自System.Object。
#
# 换句话说，它们指的是一个内存位置。使用多个变量时，引用类型可以指向一个内存位置。
# 如果内存位置的数据是由一个变量改变的，其他变量会自动反映这种值的变化。内置的 引用类型有：object、dynamic 和 string。
# 当一个值类型转换为对象类型时，则被称为 装箱；另一方面，当一个对象类型转换为值类型时，则被称为 拆箱。
# 值类型与引用类型的区别：
#
# 从内存上看，值类型是在栈中的操作，而引用类型是在堆中的操作。
#
# （导致 => 值类型存取速度快，引用类型存取速度慢。）
#
# 从本质上看，值类型表示实际数据，引用类型表示指向存储在内存堆中的数据的指针或引用。
#
# （值类型是具体的那个数值所占用的空间大小，而引用类型是存放那个数值的空间地址。）
#
# 从来源上看，值类型继承自System.ValueType，引用类型继承自System.Object。
#
# 特别的：结构体是值类型，类和string是引用类型。
#
# 当一个值类型转换为对象类型时，则被称为 装箱；另一方面，当一个对象类型转换为值类型时，则被称为 拆箱。
#
# 动态类型与对象类型相似，但是对象类型变量的类型检查是在编译时发生的，而动态类型变量的类型检查是在运行时发生的。

#接口(interface)和抽象类(abstract class)的区别

 #1、接口支持多继承，抽象类不能实现多继承。
 #2、接口只能定义抽象规则，抽象类既可以定义规则，还可能提供已实现的成员。
 #3、接口是一组行为规范，抽象类是一个不完全的类，着重族的概念。
 #4、接口可以用于支持回调，抽象类不能实现回调，因为继承不支持。
 #5、接口只包含方法、属性、索引器、事件的签名，但不能定义字段和包含实现的方法，抽象类可以定义字段、属性、包含有实现的方法。
 #6、接口可以作用于值类型和引用类型，抽象类只能作用于引用类型。例如，Struct就可以继承接口，而不能继承类。
